<?php
use Phalcon\Di;

function safeFilter($str)
{

    $html_string = array("&amp;", "&nbsp;", "'", '"', "<", ">", "\t", "\r");

    $html_clear = array("&", " ", "&#39;", "&quot;", "&lt;", "&gt;", "&nbsp; &nbsp; ", "");

    $js_string = array("/<script(.*)<\/script>/isU");

    $js_clear = array("");

    $frame_string = array("/<frame(.*)>/isU", "/<\/fram(.*)>/isU", "/<iframe(.*)>/isU", "/<\/ifram(.*)>/isU");

    $frame_clear = array("", "", "", "");

    $style_string = array("/<style(.*)<\/style>/isU", "/<link(.*)>/isU", "/<\/link>/isU");

    $style_clear = array("", "", "");

    $str = trim($str);

    //过滤字符串

    $str = str_replace($html_string, $html_clear, $str);

    //过滤JS

    $str = preg_replace($js_string, $js_clear, $str);

    //过滤ifram

    $str = preg_replace($frame_string, $frame_clear, $str);

    //过滤style

    $str = preg_replace($style_string, $style_clear, $str);

    return $str;

}

function isHome()
{
    $dispatcher = Di::getDefault()->getShared('dispatcher');
    $controllerName = strtolower($dispatcher->getControllerName());
    $actionName = strtolower($dispatcher->getActionName());
    if ($controllerName == 'index' && $actionName == 'name') {
        return true;
    }
    return false;
}

function arrayEnd($data)
{
    if (is_string($data)) {
        return $data;
    } elseif (is_array($data)) {
        return end($data);
    }
    return (string) $data;
}

function objectToArray($obj)
{
    $_arr = is_object($obj) ? get_object_vars($obj) : $obj;
    $arr = [];
    if (is_array($_arr) || is_object($_arr)) {
        foreach ($_arr as $key => $val) {
            $val = (is_array($val) || is_object($val)) ? objectToArray($val) : $val;
            $arr[$key] = $val;
        }
    }
    return $arr;
}

function formRender($form)
{
    $di = Di::getDefault();
    $formObject = $di->getShared('form')->create($form);
    if ($formObject instanceof \Core\Forms\Form) {
        return $formObject->renderForm();
    }
    return false;
}

function getClassName($className)
{
    $string = trim(strrchr($className, '\\'), '\\');
    $string = lcfirst($string);
    return $string;
}

function jsonToHierarchy($data)
{
    $output = array();
    //config::printCode($term);
    foreach ($data as $t) {
        $output[$t->id] = $t->id;
        if (isset($t->children)) {
            $output[$t->id] = jsonToHierarchy($t->children);
        }
    }
    return $output;
}

function moduleExist($module)
{
    $module = strtolower($module);
    $moduleList = Di::getDefault()->getShared('config')->get('modules');
    if (isset($moduleList[$module])) {
        return true;
    } else {
        return false;
    }
}

/**
 * 检查字符串或数组是否是合法可调用结构
 */
function isCallable($func)
{
    if (is_array($func)) {
        if (count($func) != 2) {
            return false;
        }
        return method_exists($func[0], $func[1]);
    } else {
        if (!is_callable($func)) {
            return false;
        }
        if (stristr($func, ':') !== false) {
            $funcInfo = explode('::', $func);
            if (count($funcInfo) != 2) {
                return false;
            }
            return method_exists($funcInfo[0], $funcInfo[1]);
        }
    }
    return false;
}

/**
 * @return array
 * 获取搜索引擎关键字
 */
function searchWord()
{
    $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
    if (strstr($referer, 'baidu.com')) {
        //百度
        preg_match("|baidu.+wo?r?d=([^\\&]*)|is", $referer, $tmp);
        $keyword = urldecode($tmp[1]);
        $from = 'baidu';
    } elseif (strstr($referer, 'google.com') or strstr($referer, 'google.cn')) {
        //谷歌
        preg_match("|google.+q=([^\\&]*)|is", $referer, $tmp);
        $keyword = urldecode($tmp[1]);
        $from = 'google';
    } elseif (strstr($referer, 'so.com')) {
        //360搜索
        preg_match("|so.+q=([^\\&]*)|is", $referer, $tmp);
        $keyword = urldecode($tmp[1]);
        $from = '360';
    } elseif (strstr($referer, 'sogou.com')) {
        //搜狗
        preg_match("|sogou.com.+query=([^\\&]*)|is", $referer, $tmp);
        $keyword = urldecode($tmp[1]);
        $from = 'sogou';
    } elseif (strstr($referer, 'soso.com')) {
        //搜搜
        preg_match("|soso.com.+w=([^\\&]*)|is", $referer, $tmp);
        $keyword = urldecode($tmp[1]);
        $from = 'soso';
    } else {
        $keyword = '';
        $from = '';
    }

    return array('keyword' => $keyword, 'from' => $from);
}

/**
 * 获取客户端浏览器信息 添加win10 edge浏览器判断
 * @param  null
 * @author  Jea杨
 * @return string
 */
function getBroswer()
{
    global $di;
    $sys = $di->getShared('request')->getServer('HTTP_USER_AGENT'); //获取用户代理字符串

    if (stripos($sys, "Firefox/") > 0) {
        preg_match("/Firefox\/([^;)]+)+/i", $sys, $b);
        $exp[0] = "Firefox";
        $exp[1] = $b[1]; //获取火狐浏览器的版本号
    } elseif (stripos($sys, "Maxthon") > 0) {
        preg_match("/Maxthon\/([\d\.]+)/", $sys, $aoyou);
        $exp[0] = "傲游";
        $exp[1] = $aoyou[1];
    } elseif (stripos($sys, "MSIE") > 0) {
        preg_match("/MSIE\s+([^;)]+)+/i", $sys, $ie);
        $exp[0] = "IE";
        $exp[1] = $ie[1]; //获取IE的版本号
    } elseif (stripos($sys, "OPR") > 0) {
        preg_match("/OPR\/([\d\.]+)/", $sys, $opera);
        $exp[0] = "Opera";
        $exp[1] = $opera[1];
    } elseif (stripos($sys, "Edge") > 0) {
        //win10 Edge浏览器 添加了chrome内核标记 在判断Chrome之前匹配
        preg_match("/Edge\/([\d\.]+)/", $sys, $Edge);
        $exp[0] = "Edge";
        $exp[1] = $Edge[1];
    } elseif (stripos($sys, "Chrome") > 0) {
        preg_match("/Chrome\/([\d\.]+)/", $sys, $google);
        $exp[0] = "Chrome";
        $exp[1] = $google[1]; //获取google chrome的版本号
    } elseif (stripos($sys, 'rv:') > 0 && stripos($sys, 'Gecko') > 0) {
        preg_match("/rv:([\d\.]+)/", $sys, $IE);
        $exp[0] = "IE";
        $exp[1] = $IE[1];
    } else {
        $exp[0] = "未知浏览器";
        $exp[1] = "";
    }
    return $exp[0] . '(' . $exp[1] . ')';
}

/**
 * 获取客户端操作系统信息包括win10
 * @param  null
 * @author  Jea杨
 * @return string
 */
function getOs()
{
    global $di;
    $agent = $di->getShared('request')->getServer('HTTP_USER_AGENT');

    if (preg_match('/win/i', $agent) && strpos($agent, '95')) {
        $os = 'Windows 95';
    } else if (preg_match('/win 9x/i', $agent) && strpos($agent, '4.90')) {
        $os = 'Windows ME';
    } else if (preg_match('/win/i', $agent) && preg_match('/98/i', $agent)) {
        $os = 'Windows 98';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.0/i', $agent)) {
        $os = 'Windows Vista';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.1/i', $agent)) {
        $os = 'Windows 7';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 6.2/i', $agent)) {
        $os = 'Windows 8';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 10.0/i', $agent)) {
        $os = 'Windows 10'; #添加win10判断
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 5.1/i', $agent)) {
        $os = 'Windows XP';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt 5/i', $agent)) {
        $os = 'Windows 2000';
    } else if (preg_match('/win/i', $agent) && preg_match('/nt/i', $agent)) {
        $os = 'Windows NT';
    } else if (preg_match('/win/i', $agent) && preg_match('/32/i', $agent)) {
        $os = 'Windows 32';
    } else if (preg_match('/linux/i', $agent)) {
        $os = 'Linux';
    } else if (preg_match('/unix/i', $agent)) {
        $os = 'Unix';
    } else if (preg_match('/sun/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'SunOS';
    } else if (preg_match('/ibm/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'IBM OS/2';
    } else if (preg_match('/Mac/i', $agent) && preg_match('/PC/i', $agent)) {
        $os = 'Macintosh';
    } else if (preg_match('/PowerPC/i', $agent)) {
        $os = 'PowerPC';
    } else if (preg_match('/AIX/i', $agent)) {
        $os = 'AIX';
    } else if (preg_match('/HPUX/i', $agent)) {
        $os = 'HPUX';
    } else if (preg_match('/NetBSD/i', $agent)) {
        $os = 'NetBSD';
    } else if (preg_match('/BSD/i', $agent)) {
        $os = 'BSD';
    } else if (preg_match('/OSF1/i', $agent)) {
        $os = 'OSF1';
    } else if (preg_match('/IRIX/i', $agent)) {
        $os = 'IRIX';
    } else if (preg_match('/FreeBSD/i', $agent)) {
        $os = 'FreeBSD';
    } else if (preg_match('/teleport/i', $agent)) {
        $os = 'teleport';
    } else if (preg_match('/flashget/i', $agent)) {
        $os = 'flashget';
    } else if (preg_match('/webzip/i', $agent)) {
        $os = 'webzip';
    } else if (preg_match('/offline/i', $agent)) {
        $os = 'offline';
    } else {
        $os = '未知操作系统';
    }
    return $os;
}

/*
 * 数据过滤函数
 */
function commaExplode($value)
{
    return explode(',', $value);
}

function semicolonExplode($value)
{
    return explode(';', $value);
}

function codespecialchars($value)
{
    return preg_replace_callback('/<code([^>]]*?)>(.*?)<\/code>/i', function ($matches) {
        return '<code' . $matches[1] . '>' . htmlentities($matches[2]) . '</code>';
    }, $value);
}

/*
 * 数据过滤函数结束
 */

//输出未知变量
function getVar($data, $varName, $default = null)
{
    if (is_object($data)) {
        //查询是否有render函数
        $methodName = 'render' . ucfirst($varName);
        if (method_exists($data, $methodName)) {
            return $data->{$methodName}();
        }
        //查询是否有get函数
        $methodName = 'get' . ucfirst($varName);
        if (method_exists($data, $methodName)) {
            return $data->{$methodName}();
        }
        if (isset($data->{$varName})) {
            return $data->{$varName};
        }
    } elseif (is_array($data)) {
        if (isset($data[$varName])) {
            return $data[$varName];
        }
    } elseif (is_string($data)) {
        $varName = intval($varName);
        return $data[$varName];
    }
    return $default;
}

//从数组中随机提取
function randGet($info)
{
    $infoLength = count($info);
    $randNum = rand(0, $infoLength - 1);
    if (isset($info[$randNum])) {
        return $info[$randNum];
    }
    return end($info);
}

//字段数据初始化
function formFieldInit($fields, $isWidget = true)
{
    $output = array();
    foreach ($fields as $key => $field) {
        if (isset($field['widget']) || $isWidget == false) {
            if (isset($field['widget']) && ($field['widget'] == 'GroupTabs' || $field['widget'] == 'Group')) {
                if (isset($field['group'])) {
                    $output += formFieldInit($field['group']);
                }
                if (isset($field['GroupTabs'])) {
                    $output += formFieldInit($field['GroupTabs']);
                }
            } else {
                $output[$key] = $field;
            }
        }
    }
    return $output;
}

//转换附加属性成字符串
function renderAttributes($attributes)
{
    $output = array();
    foreach ($attributes as $key => $value) {
        if (is_string($value) || is_int($value)) {
            $output[] = "$key = '$value'";
        }

    }
    return implode(' ', $output);
}

//合并上数组
function userArrayMerge($one, $two)
{
    foreach ($two as $key => $value) {
        if (isset($one[$key]) && is_array($one[$key]) && is_array($value)) {
            $one[$key] = userArrayMerge($one[$key], $value);
        } else {
            $one[$key] = $value;
        }
    }
    return $one;
}

//生成随机字符串
function randomString($length, $chars = '0123456789qwertyuiopasdfghjklzxcvbnm')
{
    $hash = '';
    $max = strlen($chars) - 1;
    for ($i = 0; $i < $length; $i++) {
        $hash .= $chars[mt_rand(0, $max)];
    }
    return $hash;
}

//隐藏敏感信息
function hiddenString($string, $length = 3)
{
    for ($i = 0; $i < $length; $i++) {
        $string[$i] = '*';
    }
    return $string;
}

//转换时间
function timeTran($the_time)
{
    //echo $now_time;
    $now_time = time();
    $show_time = $the_time;
    $the_time = date("Y年m月d日", time());
    $dur = $now_time - $show_time;
    $intDur = abs($dur);
    if ($intDur < 60) {
        $output = $intDur . '秒';
    } else {
        if ($intDur < 3600) {
            $output = floor($intDur / 60) . '分钟';
        } else {
            if ($intDur < 86400) {
                $output = floor($intDur / 3600) . '小时';
            } else {
                if ($intDur < 259200) {
                    //3天内
                    $output = floor($intDur / 86400) . '天';
                } else {
                    $output = $the_time;
                }
            }
        }
    }
    if ($output != $the_time) {
        if ($dur < 0) {
            $output .= '后';
        } else {
            $output .= '前';
        }
    }
    return $output;
}

//自动闭合html标签
function closeHtmlTags($html)
{
    preg_match_all('#<(?!meta|img|br|hr|input\b)\b([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
    $openedtags = $result[1];
    preg_match_all('#</([a-z]+)>#iU', $html, $result);
    $closedtags = $result[1];
    $len_opened = count($openedtags);
    $len_closed = count($closedtags);
    if ($len_closed == $len_opened) {
        return $html;
    }
    $openedtags = array_reverse($openedtags);
    for ($i = 0; $i < $len_opened; $i++) {
        if (!in_array($openedtags[$i], $closedtags)) {
            $html .= '</' . $openedtags[$i] . '>';
        } else {
            unset($closedtags[array_search($openedtags[$i], $closedtags)]);
        }
    }
    return $html;
}

//截取字符串，并自动闭合html标签
function subString($string, $length, $stripTags = false, $start = 0)
{
    if ($stripTags === true) {
        return strip_tags(trim(mb_substr($string, $start, $length, 'utf-8')));
    }
    return closeHtmlTags(mb_substr($string, $start, $length, 'utf-8'));
}

//获取不带参数的当前地址
function staticUrl($params = array(), $mergeQuery = true)
{
    global $di;
    $urlName = $di->getShared('router')->getMatchedRoute()->getName();
    $urlParams = $di->getShared('router')->getParams();
    $urlParams['for'] = $urlName;
    if ($mergeQuery === true && !empty($params)) {
        $query = $di->getShared('request')->getQuery();
        if (isset($query['_url'])) {
            unset($query['_url']);
        }
        $params = array_merge($query, $params);
    }
    return $di->getShared('url')->get($urlParams, $params);
}

//处理分页数据
function paginator($total, $current, $item)
{
    if ($total == 0) {
        return array();
    }
    $output = array();
    $nowItem = intval($item / 2);
    for ($i = $nowItem; $i >= 1; $i--) {
        $index = $current - $i;
        if ($index <= 1) {
            $output[1] = 1;
        } else {
            $output[$index] = $index;
        }
    }
    $output[$current] = 'current';
    for ($i = 1; $i <= $nowItem + 1; $i++) {
        $index = $current + $i;
        if ($index > $total) {
            $output[$total] = $total;
        } else {
            $output[$index] = $index;
        }
    }
    return $output;
}

//转换驼峰命名为数组
function exEntityNameInfo($str)
{
    if (is_string($str) === false) {
        //@warning The Exception is an E_ERROR in the original API
        //@note changed "camelize" to "uncamelize"
        throw new Exception('Invalid arguments supplied for uncamelize()');
    }

    $l = strlen($str);
    $output = '';

    for ($i = 0; $i < $l; ++$i) {
        $ch = ord($str[$i]);

        if ($ch === 0) {
            break;
        }

        if ($ch >= 65 && $ch <= 90) {
            if ($i > 0) {
                $output .= '_';
            }
            $output .= chr($ch + 32);
        } else {
            $output .= $str[$i];
        }
    }
    return explode('_', $output);
}

// nestableJson数据转化为数组
function nestableJsonToArray($data)
{
    $output = array();
    foreach ($data as $t) {
        $output[$t->id] = $t->id;
        if (isset($t->children)) {
            $output[$t->id] = nestableJsonToArray($t->children);
        }
    }
    return $output;
}

//从多维数组中删除某一项目
function MultArrayDeleteItem($data, $item)
{
    $output = $data;
    if (isset($data[$item])) {
        if (is_array($data[$item])) {
            $output = array_merge($data[$item], $output);
        }
        unset($output[$item]);

        return $output;
    }
    foreach ($data as $key => $value) {
        if (is_array($value)) {
            $data[$key] = MultArrayDeleteItem($value, $item);
            if (empty($data[$key])) {
                $data[$key] = $key;
            }
        }
    }
    return $data;
}

//从带附加信息多维数组中删除某一项目
function multInfoArrayDeleteItem($data, $item)
{
    $output = $data;
    if (isset($data[$item])) {
        if (is_array($data[$item]) && isset($data[$item]['son']) && !empty($data[$item]['son'])) {
            $output = array_merge($data[$item]['son'], $output);
        }
        unset($output[$item]);

        return $output;
    }
    foreach ($data as $key => $value) {
        if (is_array($value) && isset($value['son']) && !empty($value['son'])) {
            $data[$key]['son'] = multInfoArrayDeleteItem($value['son'], $item);
            if (empty($data[$key]['son'])) {
                unset($data[$key]['son']);
            }
        }
    }
    return $data;
}

function multInfoArrayValues($data)
{
    $output = [
        'sort' => [],
        'data' => [],
    ];
    foreach ($data as $key => $item) {
        $item['id'] = $key;
        $output['sort'][] = $key;
        $output['data'][$key] = $item;
        if (isset($item['son']) && !empty($item['son'])) {
            $sonOutput = multInfoArrayValues($item['son']);
            $output['sort'] = array_merge($output['sort'], $sonOutput['sort']);
            $output['data'] = array_merge($output['data'], $sonOutput['data']);
        }
    }
    return $output;
}

//从带附加信息多维数组中获得某一项的上下文信息
function multInfoArrayActionInfo(array $data, string $item)
{
    $arrayValue = multInfoArrayValues($data);
    $current = array_search($item, $arrayValue['sort']);
    $up = intval($current - 1);
    $next = intval($current + 1);
    $output = ['up' => false, 'next' => false];
    if ($up && isset($arrayValue['sort'][$up])) {
        $output['up'] = $arrayValue['data'][$arrayValue['sort'][$up]];
    }
    if ($next && isset($arrayValue['sort'][$next])) {
        $output['next'] = $arrayValue['data'][$arrayValue['sort'][$next]];
    }
    return $output;
}

//基于数组的数据库查询构建
function attachToString($attach)
{
    $output = '';
    if (is_string($attach)) {
        $output = $attach;
    } elseif (is_array($attach)) {
        $output = array();
        foreach ($attach as $value) {
            if (isset($value['key']) && isset($value['value']) && !empty($value['key']) && !empty($value['value'])) {
                $output[$value['key']] = $value['value'];
            }
        }
        $output = serialize($output);
    }
    return $output;
}

//将多维数组转为一维数组
function toFlat($a)
{
    $output = array();
    if (is_array($a)) {
        foreach ($a as $key => $value) {
            if (is_array($value)) {
                $output[$key] = $key;
                $output += toFlat($value);
            } else {
                $output[$key] = $value;
            }
        }
    }
    return $output;
}

//从多维数组中根据键名取回值
function search($a, $key)
{
    $output = array();
    $newa = array();
    if (isset($a[$key])) {
        return $a[$key];
    }
    foreach ($a as $v) {
        if (is_array($v)) {
            $a = search($v, $key);
            if ($a != false) {
                return $a;
            }
        }
    }
    return false;
}

// 以键名为值生成新数组
function toOne($items)
{
    foreach ($items as $key => $value) {
        $items[$key] = $key;
    }
    return $items;
}

//通过单一数组生成结构树
function tree($items)
{
    $tree = array();
    $oneItems = toOne($items);
    foreach ($items as $key => $item) {
        if (isset($items[$item['parent']])) {
            if (!is_array($oneItems[$item['parent']])) {
                $oneItems[$item['parent']] = array();
            }
            $oneItems[$item['parent']][$key] = &$oneItems[$key];
        } else {
            $tree[$key] = &$oneItems[$key];
        }
    }
    return $tree;
}

// 附加数据转换为数组
function attachToArray($attach)
{
    if (is_array($attach)) {
        return $attach;
    } elseif (is_string($attach)) {
        if (($attach = @unserialize($attach)) == true) {
            return $attach;
        }
    }
    return array();
}

// 获取特定尺寸的图片缩略图
function thumbnail($width, $height, $file)
{
    $urlInfo = explode('.', $file);
    if (is_string($file)) {
        $filePath = ROOT_DIR . WEB_CODE . $file;
    }
    $thumbnailUrl = $urlInfo[0] . '_' . $height . '_' . $width . '.' . $urlInfo[1];
    $thumbnailPath = ROOT_DIR . WEB_CODE . $urlInfo[0] . '_' . $height . '_' . $width . '.' . $urlInfo[1];

    if (file_exists($thumbnailPath)) {
        return $thumbnailUrl;
    } else {
        if (!file_exists($filePath)) {
            return $file;
        }
        $outputThumbnaiPath = \Core\Images::autoThumbnail($filePath, $width, $height, $thumbnailPath, 0, 0);
        if ($outputThumbnaiPath === true) {
            return $thumbnailUrl;
        }
        return $file;
    }
}
